home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / sndhrdw / seibu.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  6KB  |  217 lines

  1. /***************************************************************************
  2.  
  3.     Seibu Sound System v1.02, designed 1986 by Seibu Kaihatsu
  4.  
  5.     The Seibu sound system comprises of a Z80A, a YM3812, a YM3931*, and
  6.     an Oki MSM6205.  As well as sound the Z80 can controls coins and pass
  7.     data to the main cpu.  There are a few little quirks that make it
  8.     worthwhile emulating in a seperate file:
  9.  
  10.     * The YM3812 generates interrupt RST10, by asserting the interrupt line,
  11.     and placing 0xd7 on the data bus.
  12.  
  13.     * The main cpu generates interrupt RST18, by asserting the interrupt line,
  14.     and placing 0xdf on the data bus.
  15.  
  16.     A problem can occur if both the YM3812 and the main cpu try to assert
  17.     the interrupt line at the same time.  The effect in the old Mame
  18.     emulation would be for sound to stop playing - this is because a RST18
  19.     cancelled out a RST10, and if a single RST10 is dropped sound stops
  20.     as the YM3812 timer is not reset.  The problem occurs because even
  21.     if both interrupts happen at the same time, there can only be one value
  22.     on the data bus.  Obviously the real hardware must have some circuit
  23.     to prevent this.  It is emulated by user timers to control the z80
  24.     interrupt vector.
  25.  
  26.     (*What on earth _is_ the YM3931??  There are no unknown memory writes)
  27.  
  28.     Emulation by Bryan McPhail, mish@tendril.co.uk
  29.  
  30. ***************************************************************************/
  31.  
  32. #include "driver.h"
  33. #include "sndhrdw/seibu.h"
  34.  
  35. static int sound_cpu;
  36. unsigned char *seibu_shared_sound_ram;
  37.  
  38. /***************************************************************************/
  39.  
  40. enum
  41. {
  42.     VECTOR_INIT,
  43.     RST10_ASSERT,
  44.     RST10_CLEAR,
  45.     RST18_ASSERT,
  46.     RST18_CLEAR
  47. };
  48.  
  49. static void setvector_callback(int param)
  50. {
  51.     static int irq1,irq2;
  52.  
  53.     switch(param)
  54.     {
  55.         case VECTOR_INIT:
  56.             irq1 = irq2 = 0xff;
  57.             break;
  58.  
  59.         case RST10_ASSERT:
  60.             irq1 = 0xd7;
  61.             break;
  62.  
  63.         case RST10_CLEAR:
  64.             irq1 = 0xff;
  65.             break;
  66.  
  67.         case RST18_ASSERT:
  68.             irq2 = 0xdf;
  69.             break;
  70.  
  71.         case RST18_CLEAR:
  72.             irq2 = 0xff;
  73.             break;
  74.     }
  75.  
  76.     cpu_irq_line_vector_w(sound_cpu,0,irq1 & irq2);
  77.     if ((irq1 & irq2) == 0xff)    /* no IRQs pending */
  78.         cpu_set_irq_line(sound_cpu,0,CLEAR_LINE);
  79.     else    /* IRQ pending */
  80.         cpu_set_irq_line(sound_cpu,0,ASSERT_LINE);
  81. }
  82.  
  83. WRITE_HANDLER( seibu_rst10_ack_w )
  84. {
  85.     /* Unused for now */
  86. }
  87.  
  88. WRITE_HANDLER( seibu_rst18_ack_w )
  89. {
  90.     timer_set(TIME_NOW,RST18_CLEAR,setvector_callback);
  91. }
  92.  
  93. void seibu_ym3812_irqhandler(int linestate)
  94. {
  95.     if (linestate)
  96.         timer_set(TIME_NOW,RST10_ASSERT,setvector_callback);
  97.     else
  98.         timer_set(TIME_NOW,RST10_CLEAR,setvector_callback);
  99. }
  100.  
  101. /***************************************************************************/
  102.  
  103. /* Use this if the sound cpu is cpu 1 */
  104. void seibu_sound_init_1(void)
  105. {
  106.     sound_cpu=1;
  107.     setvector_callback(VECTOR_INIT);
  108. }
  109.  
  110. /* Use this if the sound cpu is cpu 2 */
  111. void seibu_sound_init_2(void)
  112. {
  113.     sound_cpu=2;
  114.     setvector_callback(VECTOR_INIT);
  115. }
  116.  
  117. /***************************************************************************/
  118.  
  119. WRITE_HANDLER( seibu_bank_w )
  120. {
  121.     unsigned char *RAM;
  122.  
  123.     if (sound_cpu==1) RAM = memory_region(REGION_CPU2);
  124.     else RAM = memory_region(REGION_CPU3);
  125.  
  126.     if (data&1) { cpu_setbank(1,&RAM[0x0000]); }
  127.     else { cpu_setbank(1,&RAM[0x10000]); }
  128. }
  129.  
  130. READ_HANDLER( seibu_soundlatch_r )
  131. {
  132.     return seibu_shared_sound_ram[offset<<1];
  133. }
  134.  
  135. WRITE_HANDLER( seibu_soundclear_w )
  136. {
  137.     seibu_shared_sound_ram[0]=data;
  138. }
  139.  
  140. WRITE_HANDLER( seibu_soundlatch_w )
  141. {
  142.     seibu_shared_sound_ram[offset]=data;
  143.     if (offset==0xc && seibu_shared_sound_ram[0]!=0)
  144.         timer_set(TIME_NOW,RST18_ASSERT,setvector_callback);
  145. }
  146.  
  147. WRITE_HANDLER( seibu_main_data_w )
  148. {
  149.     seibu_shared_sound_ram[offset<<1]=data;
  150. }
  151.  
  152. /***************************************************************************/
  153.  
  154. static READ_HANDLER( sound_cpu_spin_r )
  155. {
  156.     unsigned char *RAM;
  157.  
  158.     if (sound_cpu==1) RAM = memory_region(REGION_CPU2);
  159.     else RAM = memory_region(REGION_CPU3);
  160.  
  161.     if (cpu_get_pc()==0x129 && RAM[0x201c]==0)
  162.         cpu_spinuntil_int();
  163.  
  164.     return RAM[0x201c+offset];
  165. }
  166.  
  167. void install_seibu_sound_speedup(int cpu)
  168. {
  169.     install_mem_read_handler(cpu, 0x201c, 0x201d, sound_cpu_spin_r);
  170. }
  171.  
  172. /***************************************************************************/
  173.  
  174. /* NOTICE!  This is not currently correct, this table works for the first
  175. 128 bytes, but goes wrong after that.  I suspect the bytes in this table
  176. are shifted according to an address line.  I have not confirmed the pattern
  177. repeats after 128 bytes, it may be more...
  178.  
  179. There is also a 0xff fill at the end of the rom.
  180.  
  181. */
  182.  
  183. /* Game using encrypted sound cpu - Raiden, Dynamite Duke, Dead Angle */
  184. void seibu_sound_decrypt(void)
  185. {
  186.     unsigned char *RAM = memory_region(REGION_CPU3);
  187.     int xor_table[128]={
  188.         0x00,0x00,0x10,0x10,0x08,0x00,0x00,0x18,
  189.         0x00,0x00,0x10,0x10,0x08,0x08,0x18,0x18,
  190.  
  191.         0x00,0x00,0x00,0x10,0x08,0x08,0x18,0x18,
  192.         0x00,0x00,0x00,0x10,0x08,0x08,0x18,0x18,
  193.  
  194.         0x00,0x00,0x10,0x10,0x08,0x08,0x18,0x18,
  195.         0x00,0x00,0x10,0x10,0x08,0x08,0x18,0x18,
  196.  
  197.         0x00,0x00,0x10,0x10,0x08,0x08,0x18,0x18,
  198.         0x00,0x00,0x10,0x10,0x08,0x08,0x18,0x18,
  199.  
  200.         0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08,
  201.         0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08,
  202.  
  203.         0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08,
  204.         0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08,
  205.  
  206.         0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08,
  207.         0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08,
  208.  
  209.         0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08,
  210.         0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08,
  211.     };
  212.     int i;
  213.  
  214.     for (i=0; i<0x18000; i++)
  215.         RAM[i]=RAM[i]^xor_table[i%128];
  216. }
  217.